package com.codedancer.campus.client.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.codedancer.campus.client.service.IConfessionalWallCommentService;
import com.codedancer.campus.client.service.bo.confessionalWallComment.CommentAddBo;
import com.codedancer.campus.client.service.bo.confessionalWallComment.ConfessionalWallCommentPageSearchBo;
import com.codedancer.campus.client.service.vo.confessionalWallComment.ConfessionalWallCommentVo;
import com.codedancer.campus.common.exception.BusinessException;
import com.codedancer.campus.common.utils.SensitiveWordsDetectUtil;
import com.codedancer.campus.common.utils.UUIDGenerator;
import com.codedancer.campus.mapper.ConfessionalWallCommentMapper;
import com.codedancer.campus.mapper.ConfessionalWallMapper;
import com.codedancer.campus.mapper.UserMapper;
import com.codedancer.campus.po.ConfessionalWall;
import com.codedancer.campus.po.ConfessionalWallComment;
import com.codedancer.campus.po.User;
import com.codedancer.campus.qo.confessionalWallComment.ConfessionalWallCommentPageSearchQo;
import com.google.common.collect.Lists;
import java.util.List;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional(rollbackFor = Exception.class)
public class ConfessionalWallCommentServiceImpl implements IConfessionalWallCommentService {

  @Autowired
  private ConfessionalWallCommentMapper confessionalWallCommentMapper;
  @Autowired
  private ConfessionalWallMapper confessionalWallMapper;
  @Autowired
  private UserMapper userMapper;
  @Autowired
  private SensitiveWordsDetectUtil detectUtil;

  /**
   * 表白墙评论
   *
   * @param commentAddBo
   */
  @Override
  public void add(CommentAddBo commentAddBo) {
    if (!confessionalWallMapper.existsByUuId(commentAddBo.getConfessionalWallUuid())) {
      throw new BusinessException("表白墙不存在");
    }
    if (detectUtil.checkContent(commentAddBo.getContent())) {
      throw new BusinessException("内容存在敏感词汇，请检查");
    }
    ConfessionalWallComment confessionalWallComment = new ConfessionalWallComment();
    confessionalWallComment.setUuid(UUIDGenerator.getUUID());
    confessionalWallComment.setCommentUserUuid(commentAddBo.getCurrentUserUuid());
    confessionalWallComment.setConfessionalWallUuid(commentAddBo.getConfessionalWallUuid());
    confessionalWallComment.setRepliedUserUuid(commentAddBo.getRepliedUserUuid());
    confessionalWallComment.setContent(commentAddBo.getContent());
    confessionalWallCommentMapper.insert(confessionalWallComment);
  }

  /**
   * 分页查询表白墙父级评论
   *
   * @param confessionalWallCommentPageSearchBo
   * @return
   */
  @Override
  public IPage<ConfessionalWallCommentVo> pageParentComment(
      ConfessionalWallCommentPageSearchBo confessionalWallCommentPageSearchBo) {
    ConfessionalWallCommentPageSearchQo confessionalWallCommentPageSearchQo = BeanUtil
        .copyProperties(confessionalWallCommentPageSearchBo,
            ConfessionalWallCommentPageSearchQo.class);
    ConfessionalWall confessionalWall = confessionalWallMapper
        .findById(confessionalWallCommentPageSearchBo.getConfessionalWallUuid())
        .orElseThrow(() -> new BusinessException("表白墙不存在"));
    IPage<ConfessionalWallComment> confessionalWallCommentIPage = null;
    if (confessionalWall.getIsOpenComment()) {
      confessionalWallCommentIPage = confessionalWallCommentMapper
          .pageParentComment(
              new Page<ConfessionalWallComment>(confessionalWallCommentPageSearchBo.getPage(),
                  confessionalWallCommentPageSearchBo.getSize()),
              confessionalWallCommentPageSearchQo);
    }
    IPage<ConfessionalWallCommentVo> confessionalWallCommentVoIPage = new Page<>();
    List<ConfessionalWallCommentVo> confessionalWallCommentVos = Lists.newArrayList();
    assert confessionalWallCommentIPage != null;
    if (CollectionUtil.isNotEmpty(confessionalWallCommentIPage.getRecords())) {
      confessionalWallCommentVos = confessionalWallCommentIPage.getRecords().stream()
          .map(confessionalWallComment -> {
            ConfessionalWallCommentVo confessionalWallCommentVo = BeanUtil
                .copyProperties(confessionalWallComment, ConfessionalWallCommentVo.class);
            confessionalWallCommentVo.setCommentTime(confessionalWallComment.getCreateTime());
            User user = userMapper.selectById(confessionalWallComment.getCommentUserUuid());
            confessionalWallCommentVo.setCommentNickName(user.getNickName());
            confessionalWallCommentVo.setCommentAvatar(user.getAvatar());
            // 判断父级评论是否有儿子
            confessionalWallCommentVo.setHasChildren(
                confessionalWallCommentMapper.hasChildren(confessionalWallComment.getUuid()));
            return confessionalWallCommentVo;
          }).collect(Collectors.toList());
    }
    confessionalWallCommentVoIPage.setRecords(confessionalWallCommentVos);
    confessionalWallCommentVoIPage.setTotal(confessionalWallCommentIPage.getTotal());
    return confessionalWallCommentVoIPage;
  }

  /**
   * 表白墙回复
   *
   * @param commentAddBo
   */
  @Override
  public void reply(CommentAddBo commentAddBo) {
    ConfessionalWallComment parentConfessionalWallComment = confessionalWallCommentMapper.findById(
            commentAddBo.getConfessionalWallCommentUuid())
        .orElseThrow(() -> new BusinessException("表白墙评论已不存在"));
    ConfessionalWallComment confessionalWallComment = new ConfessionalWallComment();
    confessionalWallComment.setUuid(UUIDGenerator.getUUID());
    confessionalWallComment.setConfessionalWallUuid(
        parentConfessionalWallComment.getConfessionalWallUuid());
    confessionalWallComment.setCommentUserUuid(commentAddBo.getCurrentUserUuid());
    confessionalWallComment.setRepliedUserUuid(commentAddBo.getRepliedUserUuid());
    // 判断该评论是否是顶级
    if (parentConfessionalWallComment.getParentUuid().equals("0")) {
      // 是顶级评论，则需要将该评论的uuid作为下一级的parentUuid
      confessionalWallComment.setParentUuid(parentConfessionalWallComment.getUuid());
    } else {
      // 否则将父级的parentUuid，最为下级的parentUuid
      confessionalWallComment.setParentUuid(parentConfessionalWallComment.getParentUuid());
    }
    confessionalWallComment.setContent(commentAddBo.getContent());
    confessionalWallCommentMapper.insert(confessionalWallComment);
  }

  /**
   * 分页查询该评论下子集评论
   *
   * @param confessionalWallCommentPageSearchBo
   * @return
   */
  @Override
  public IPage<ConfessionalWallCommentVo> pageChildrenComment(
      ConfessionalWallCommentPageSearchBo confessionalWallCommentPageSearchBo) {
    ConfessionalWallCommentPageSearchQo confessionalWallCommentPageSearchQo = BeanUtil.copyProperties(
        confessionalWallCommentPageSearchBo, ConfessionalWallCommentPageSearchQo.class);
    IPage<ConfessionalWallComment> confessionalWallCommentIPage = confessionalWallCommentMapper.pageChildrenComment(
        new Page<ConfessionalWallComment>(confessionalWallCommentPageSearchBo.getPage(),
            confessionalWallCommentPageSearchBo.getSize()),
        confessionalWallCommentPageSearchQo);
    IPage<ConfessionalWallCommentVo> confessionalWallCommentVoIPage = new Page<>();
    List<ConfessionalWallCommentVo> confessionalWallCommentVos;
    confessionalWallCommentVos = confessionalWallCommentIPage.getRecords().stream()
        .map(confessionalWallComment -> {
          ConfessionalWallCommentVo confessionalWallCommentVo = BeanUtil
              .copyProperties(confessionalWallComment, ConfessionalWallCommentVo.class);
          confessionalWallCommentVo.setCommentTime(confessionalWallComment.getCreateTime());
          User user = userMapper.selectById(confessionalWallComment.getCommentUserUuid());
          confessionalWallCommentVo.setCommentNickName(user.getNickName());
          confessionalWallCommentVo.setCommentAvatar(user.getAvatar());
          // 判断父级评论是否有儿子
          confessionalWallCommentVo.setHasChildren(
              confessionalWallCommentMapper.hasChildren(confessionalWallComment.getUuid()));
          // 查询被回复用户
          User repliedUser = userMapper.selectById(confessionalWallComment.getRepliedUserUuid());
          confessionalWallCommentVo.setRepliedNickName(repliedUser.getNickName());
          return confessionalWallCommentVo;
        }).collect(Collectors.toList());
    confessionalWallCommentVoIPage.setRecords(confessionalWallCommentVos);
    confessionalWallCommentVoIPage.setTotal(confessionalWallCommentIPage.getTotal());
    confessionalWallCommentVoIPage.setPages(confessionalWallCommentIPage.getPages());
    confessionalWallCommentVoIPage.setSize(confessionalWallCommentPageSearchBo.getSize());
    return confessionalWallCommentVoIPage;
  }

  /**
   * 删除评论
   *
   * @param confessionalWallCommentUuid
   */
  @Override
  public void delete(String confessionalWallCommentUuid) {
    if (!confessionalWallCommentMapper.existsByUuId(confessionalWallCommentUuid)) {
      throw new BusinessException("评论不存在");
    }
    // 将下面的子集评论全部删除
    confessionalWallCommentMapper.deleteByColumn("parent_uuid", confessionalWallCommentUuid);
    // 删除掉该评论
    confessionalWallCommentMapper.deleteById(confessionalWallCommentUuid);
  }
}
